#ifndef _AVERAGE_LIB_H_
#define _AVERAGE_LIB_H_

#include "stdint.h"
#include "math.h"
#include "stdbool.h"

// 滑动平均结构体
typedef struct
{
    int *data;       // 存储数据的数组
    int head;        // 指向下一个要写入的位置
    int sum;         // 当前窗口内所有数据的和
    int count;       // 当前窗口内有效数据的数量
    int window_size; // 窗口大小
} MovingAverage_handle;

/**
 * @brief 创建一个滑动平均处理器的句柄
 *
 * 分配并初始化一个滑动平均处理器所需的资源，包括动态分配用于存储数据的数组，并设置初始参数。
 * 返回指向新创建的滑动平均处理器的句柄的指针。如果窗口大小小于2或内存分配失败，则返回NULL。
 *
 * @param window_size 滑动平均窗口的大小。
 *
 * @return 指向新创建的滑动平均处理器的句柄的指针，如果创建失败则返回NULL。
 */
MovingAverage_handle *MovingAverage_handle_create(int window_size);

/**
 * @brief 删除并释放滑动平均处理器资源
 *
 * 释放与给定滑动平均处理器句柄相关联的所有资源，包括动态分配的数据数组和句柄本身，并将句柄指针置为NULL。
 *
 * @param handle 指向要删除的滑动平均处理器句柄的指针的地址。
 *
 * @return 0 表示成功释放资源，非0 值表示失败（例如，如果handle为NULL）。
 *
 * @note 调用此函数后，通过handle指针访问的资源将不再有效。
 */
int MovingAverage_handle_del(MovingAverage_handle **handle);

/**
 * @brief 更新滑动平均并获取当前平均值
 *
 * 将新值添加到滑动平均计算中，并根据当前窗口内的数据计算并返回当前的滑动平均值。
 * 如果窗口未满，则直接添加新值到窗口中。如果窗口已满，则移除最旧的值并添加新值。
 *
 * @param ma 指向滑动平均处理器的句柄。
 * @param newValue 要添加到滑动平均中的新整数值。
 * @param out_val 指向用于存储计算出的滑动平均值（整数类型）的指针。
 * 注意：由于整数除法，*out_val可能失去精度。
 *
 * @return 0 表示成功更新并计算平均值，非0 值表示失败（例如，如果ma或out_val为NULL）。
 *
 * @note *out_val的值可能由于整数除法而四舍五入到最接近的整数，从而失去小数部分的精度。
 */
int updateMovingAverage(MovingAverage_handle *ma, int newValue, int *out_val);

#endif